#pragma once

#include <iostream>
#include <string>
#include <set>

const int line_size = 1024;

class Command
{
public:
    Command()
    {
        _white_list.insert("ls");
        _white_list.insert("pwd");
        _white_list.insert("cd");
        _white_list.insert("ls -l");
        _white_list.insert("cat");

    }

    bool SafeCheck(const std::string &cmdstr)
    {
        auto iter = _white_list.find(cmdstr);
        return iter == _white_list.end() ? false : true;
    }

    // 给我一个命令字符串，我会执行它并返回执行结果
    std::string Execute(std::string cmdstr)
    {
        // 1.pipe
        // 2.fork + dup2(pipe[1],1) + exec* ,执行结果给父进程,pipe[0]
        // 3.return
        // FILE *popen(const char *command, const char *type);

        // 先不管pipe，先用fork+exec执行命令

        if(!SafeCheck(cmdstr))
        {
            return std::string(cmdstr + ": Command not allowed");
        }

        FILE *fp = popen(cmdstr.c_str(),"r");
        if(fp == nullptr)
        {
            return std::string(cmdstr + ": Failed");
        }
        
        char buffer[line_size];
        std::string result;
        while(true)
        {
            char *ret = ::fgets(buffer,line_size,fp);
            if(!ret) break;
            result += ret;
        }


        pclose(fp);
        return result.empty() ? std::string("Done") : result;
    }
private:
    std::set<std::string> _white_list;
};